import { login } from '../services/user'
import sha256 from 'js-sha256'

// 参照 ant design pro
const httpCodeMessage = {
  200: "服务器成功返回请求的数据。",
  201: "新建或修改数据成功。",
  202: "一个请求已经进入后台排队（异步任务）。",
  204: "删除数据成功。",
  400: "发出的请求有错误，服务器没有进行新建或修改数据的操作。",
  401: "用户没有权限（令牌、用户名、密码错误）。",
  403: "用户得到授权，但是访问是被禁止的。",
  404: "发出的请求针对的是不存在的记录，服务器没有进行操作。",
  406: "请求的格式不可得。",
  410: "请求的资源被永久删除，且不会再得到的。",
  422: "当创建一个对象时，发生一个验证错误。",
  500: "服务器发生错误，请检查服务器。",
  502: "网关错误。",
  503: "服务不可用，服务器暂时过载或维护。",
  504: "网关超时。",
};

const miniCodeMessage = {
  11: "无权跨域。",
  12: "网络出错。",
  13: "超时。",
  14: "解码失败。",
  19: "HTTP错误。",
  20: "请求已被停止/服务端限流。",
};

/**
 * 判断状态是否正常
 * @param {number} status
 * @returns {boolean} 状态是否正常
 */
function isStatusSuccess(status) {
  if (status >= 200 && status < 300) {
    return true;
  }
  return false;
}

/**
 *
 * @param {string} url 路径
 * @param {object} options request 额外配置
 * @returns {Promise}
 */
export function request(url, options) {
  return new Promise((resolve, reject) => {
    const requestConfig = {
      url,
      ...options,
      success(response) {
        const { status, data } = response;
        if (isStatusSuccess(status)) {
          resolve(data);
        } else {
          reject({
            error: status,
            errorMessage: data.message || httpCodeMessage[status],
          });
        }
      },
      fail(response) {
        const { error, errorMessage = miniCodeMessage[error] } = response;
        my.showToast({
          type: "exception",
          content: errorMessage,
          duration: 3000,
        });
        reject({
          error,
          errorMessage,
        });
      },
    };

    my.request(requestConfig);
  });
}

const transformResObj = (obj) => {
  const { status, data, code, desc } = obj

  obj.code = status ? status.state : code
  obj.data = data || {}
  obj.msg  = desc || status.msg

  return obj
}

const Token_Key = 'x-u-token'

export function get(url, params = {}) {
  return post(url, params, false, 'GET')
}

export function post(url, params = {}, isSilence=false, method='POST') {
  var timestamp = new Date().valueOf()
  params.timestamp = timestamp
  params = objKeySort(params)

  let signkey = `${parseParam(params)}&signKey=${timestamp}`
  params.sign = sha256(signkey)
  return new Promise((resolve, reject) => {
    let token = my.getStorageSync({ key: 'token' }).data
    
    my.request({
      url: url,
      method,
      data: params,
      headers: {
        [Token_Key]: token || '',
      },
      success: function (res) {
        const data = transformResObj(res.data || {})

        if (res.headers[Token_Key] || data.data.token) {
          my.setStorageSync({ key: 'token', data: res.headers[Token_Key] || data.data.token })
        }

        if (data.code == 0) {
          resolve(data)
        } else {
          my.showToast({
            type: 'fail',
            content: data.msg || '服务器异常',
            duration: 2000
          })

          resolve(data)
        }
      },
      fail: function (res) {
        const data = transformResObj(res.data || {})

        if (data.code === "000998" || data.code == 5) {
          my.showToast({
            type: 'fail',
            content: '请先登录',
            duration: 2000,
            success () {
              my.switchTab({url: '/pages/my/my'})
            }
          });
        } else {
          !isSilence && my.showToast({
            type: 'fail',
            content: data.msg || '服务器异常',
            duration: 2000
          })

          reject(transformResObj(res.data))
        }
      },
      complete: function (res) {
        my.hideLoading()
      }
    });
  })
}
var parseParam = function (param, key, encode) {
  if (param == null) return ''
  var arr = []
  var t = typeof param
  if (t == 'string' || t == 'number' || t == 'boolean') {
    arr.push(
      key + '=' + (encode == null || encode ? param : param)
    )
  } else {
    for (var i in param) {
      var k =
        key == null ?
          i :
          key + (param instanceof Array ? '[' + i + ']' : '.' + i)
      arr.push(parseParam(param[i], k, encode))
    }
  }
  return arr.join('&')
}

function objKeySort(obj) {
  //排序的函数
  var newkey = Object.keys(obj).sort() //先用Object内置类的keys方法获取要排序对象的属性名，再利用Array原型上的sort方法对获取的属性名进行排序，newkey是一个数组
  var newObj = {} //创建一个新的对象，用于存放排好序的键值对
  for (var i = 0; i < newkey.length; i++) {
    //遍历newkey数组
    newObj[newkey[i]] = obj[newkey[i]] //向新创建的对象中按照排好的顺序依次增加键值对
  }
  return newObj //返回排好序的新对象
}
